package com.feiyun.config;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feiyun.mapper.WxAccessTokenMapper;
import com.feiyun.model.entity.User;
import com.feiyun.model.entity.WxAccessToken;
import com.feiyun.util.LocalDateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

@Slf4j
@Component

public class WeChatUtil {

    @Resource
    private WxAccessTokenMapper wxAccessTokenMapperBean;

    private static WxAccessTokenMapper wxAccessTokenMapper;

    @Resource
    private WechatMiniAppConfig wechatMiniAppConfigBean;
    private static WechatMiniAppConfig wechatMiniAppConfig;

    private final static String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";


    private final static String GET_USER_PHONE_NUM_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=";
    @PostConstruct
    public void init() {
        wxAccessTokenMapper = wxAccessTokenMapperBean;
        wechatMiniAppConfig = wechatMiniAppConfigBean;
    }

        /**
         * 请求微信接口服务，获取小程序全局唯一后台接口调用凭据（access_token）
         * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
         * @return
         */
    public static String getAccessToken() {

        String accessToken = new WeChatUtil().getOldAccessToken();
        String result = null;
        if (accessToken == null){
            try {
                HashMap<String, String> requestParam = new HashMap<>();
                // 小程序 appId
                requestParam.put("grant_type", "client_credential");
                // 小程序唯一凭证id appid:(换成自己的)
                requestParam.put("appid", wechatMiniAppConfig.getAppid());
                // 小程序 appSecret（小程序的唯一凭证密钥,换成自己的）
                requestParam.put("secret", wechatMiniAppConfig.getAppsecret());
                // 发送GET请求读取调用微信接口获取openid用户唯一标识

                result = HttpUtils.doGet(GET_ACCESS_TOKEN_URL, requestParam);
                log.info("访问微信接口获取code，返回结果：{}",result);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            return accessToken;
        }
        JSONObject resultJson = JSONObject.parseObject(result);
        if (resultJson.get("errcode") !=null){
            log.error("获取token失败，请及时检查原因");
            return null;
        }
        accessToken = resultJson.getString("access_token");
        WxAccessToken wxAccessToken = new WxAccessToken();
        wxAccessToken.setAccessToken(accessToken);
        wxAccessToken.setExpiresIn(wechatMiniAppConfig.getExpiresIn());
        wxAccessToken.setCreateDate(LocalDateUtils.getNowDate());
        wxAccessTokenMapper.insert(wxAccessToken);
        return accessToken;
    }

    /**
     * 请求微信接口服务，用code换取用户手机号（每个code只能使用一次，code的有效期为5min）
     * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/phonenumber/phonenumber.getPhoneNumber.html
     *
     * @param code
     * @param accessToken
     * @return
     */
    public static JSONObject getPhoneNumber(String code, String accessToken) {
        String result = null;
        try {
            // 接口调用凭证：accessToken
            String baseUrl = GET_USER_PHONE_NUM_URL + accessToken;
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("code",code);
            // 手机号调用凭证
            // 发送post请求读取调用微信接口获取openid用户唯一标识
            result = HttpUtils.doPostJson(baseUrl, jsonObject.toJSONString());
            log.info("访问微信接口获取手机号，返回结果：{}",result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONObject.parseObject(result);
    }

    public String getOldAccessToken(){

        QueryWrapper<WxAccessToken> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("create_date");
        List<WxAccessToken> wxAccessTokens = wxAccessTokenMapper.selectList(wrapper);
        if (wxAccessTokens == null || wxAccessTokens.size() == 0){
            return null;
        }
        WxAccessToken wxAccessToken = wxAccessTokens.get(0);
        //数据库没有就获取最新的
        if (wxAccessTokens == null){
            return null;
        }
        //判断是否过期。获取创建时间
        LocalDateTime createDate = wxAccessToken.getCreateDate();
        LocalDateTime nowDate = LocalDateUtils.getNowDate();
        Duration between = Duration.between(createDate, nowDate);
        long seconds = between.getSeconds();
        if (seconds < 5400) {
            return wxAccessToken.getAccessToken();
        }else {
            wxAccessTokenMapper.deleteById(wxAccessToken.getId());
            log.info("当前accessToken:{},相差时间：{},快要过期,请重新获取",wxAccessToken.getAccessToken(),seconds);
            return null;
        }
    }
}